/**
 * 后端数据验证工具函数
 */

/**
 * 验证规则类型
 */
export interface ValidationRule {
  required?: boolean;
  type?: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'email' | 'phone' | 'url';
  min?: number;
  max?: number;
  pattern?: RegExp;
  custom?: (value: any) => boolean | string;
  message?: string;
}

/**
 * 验证结果类型
 */
export interface ValidationResult {
  valid: boolean;
  errors: Record<string, string>;
}

/**
 * 验证单个字段
 */
export function validateField(value: any, rules: ValidationRule): string | null {
  // 检查必填
  if (rules.required && (value === undefined || value === null || value === '')) {
    return rules.message || '此字段为必填项';
  }
  
  // 如果值为空且不是必填，则跳过其他验证
  if (!rules.required && (value === undefined || value === null || value === '')) {
    return null;
  }
  
  // 类型验证
  if (rules.type) {
    switch (rules.type) {
      case 'string':
        if (typeof value !== 'string') {
          return rules.message || '必须是字符串类型';
        }
        break;
      case 'number':
        if (typeof value !== 'number' || isNaN(value)) {
          return rules.message || '必须是数字类型';
        }
        break;
      case 'boolean':
        if (typeof value !== 'boolean') {
          return rules.message || '必须是布尔类型';
        }
        break;
      case 'array':
        if (!Array.isArray(value)) {
          return rules.message || '必须是数组类型';
        }
        break;
      case 'object':
        if (typeof value !== 'object' || Array.isArray(value) || value === null) {
          return rules.message || '必须是对象类型';
        }
        break;
      case 'email':
        if (!isValidEmail(value)) {
          return rules.message || '邮箱格式不正确';
        }
        break;
      case 'phone':
        if (!isValidPhone(value)) {
          return rules.message || '手机号格式不正确';
        }
        break;
      case 'url':
        if (!isValidUrl(value)) {
          return rules.message || 'URL格式不正确';
        }
        break;
    }
  }
  
  // 长度/大小验证
  if (rules.min !== undefined) {
    if (typeof value === 'string' || Array.isArray(value)) {
      if (value.length < rules.min) {
        return rules.message || `长度不能少于${rules.min}`;
      }
    } else if (typeof value === 'number') {
      if (value < rules.min) {
        return rules.message || `值不能小于${rules.min}`;
      }
    }
  }
  
  if (rules.max !== undefined) {
    if (typeof value === 'string' || Array.isArray(value)) {
      if (value.length > rules.max) {
        return rules.message || `长度不能超过${rules.max}`;
      }
    } else if (typeof value === 'number') {
      if (value > rules.max) {
        return rules.message || `值不能大于${rules.max}`;
      }
    }
  }
  
  // 正则表达式验证
  if (rules.pattern && typeof value === 'string') {
    if (!rules.pattern.test(value)) {
      return rules.message || '格式不正确';
    }
  }
  
  // 自定义验证
  if (rules.custom) {
    const result = rules.custom(value);
    if (typeof result === 'string') {
      return result;
    }
    if (!result) {
      return rules.message || '验证失败';
    }
  }
  
  return null;
}

/**
 * 验证对象
 */
export function validateObject(
  data: Record<string, any>,
  schema: Record<string, ValidationRule>
): ValidationResult {
  const errors: Record<string, string> = {};
  
  Object.entries(schema).forEach(([field, rules]) => {
    const error = validateField(data[field], rules);
    if (error) {
      errors[field] = error;
    }
  });
  
  return {
    valid: Object.keys(errors).length === 0,
    errors,
  };
}

/**
 * 验证邮箱格式
 */
export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

/**
 * 验证手机号格式（中国大陆）
 */
export function isValidPhone(phone: string): boolean {
  const phoneRegex = /^1[3-9]\d{9}$/;
  return phoneRegex.test(phone);
}

/**
 * 验证身份证号格式（中国大陆）
 */
export function isValidIdCard(idCard: string): boolean {
  const idCardRegex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  return idCardRegex.test(idCard);
}

/**
 * 验证URL格式
 */
export function isValidUrl(url: string): boolean {
  try {
    new URL(url);
    return true;
  } catch {
    return false;
  }
}

/**
 * 验证IP地址格式
 */
export function isValidIP(ip: string): boolean {
  const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  return ipRegex.test(ip);
}

/**
 * 验证密码强度
 */
export function validatePasswordStrength(password: string): {
  valid: boolean;
  score: number;
  feedback: string[];
} {
  const feedback: string[] = [];
  let score = 0;
  
  if (password.length < 8) {
    feedback.push('密码长度至少8位');
  } else {
    score += 1;
  }
  
  if (!/[a-z]/.test(password)) {
    feedback.push('密码应包含小写字母');
  } else {
    score += 1;
  }
  
  if (!/[A-Z]/.test(password)) {
    feedback.push('密码应包含大写字母');
  } else {
    score += 1;
  }
  
  if (!/\d/.test(password)) {
    feedback.push('密码应包含数字');
  } else {
    score += 1;
  }
  
  if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
    feedback.push('密码应包含特殊字符');
  } else {
    score += 1;
  }
  
  return {
    valid: score >= 3,
    score,
    feedback,
  };
}

/**
 * 验证用户名格式
 */
export function isValidUsername(username: string): boolean {
  // 用户名只能包含字母、数字、下划线，长度3-20位
  const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;
  return usernameRegex.test(username);
}

/**
 * 验证银行卡号格式
 */
export function isValidBankCard(cardNumber: string): boolean {
  // 简单的银行卡号验证（16-19位数字）
  const cardRegex = /^\d{16,19}$/;
  return cardRegex.test(cardNumber);
}

/**
 * 验证中文姓名格式
 */
export function isValidChineseName(name: string): boolean {
  const nameRegex = /^[\u4e00-\u9fa5]{2,10}$/;
  return nameRegex.test(name);
}

/**
 * 验证数字范围
 */
export function isNumberInRange(num: number, min: number, max: number): boolean {
  return num >= min && num <= max;
}

/**
 * 验证日期格式
 */
export function isValidDateFormat(dateString: string, format: string = 'YYYY-MM-DD'): boolean {
  const formatRegexMap: Record<string, RegExp> = {
    'YYYY-MM-DD': /^\d{4}-\d{2}-\d{2}$/,
    'YYYY/MM/DD': /^\d{4}\/\d{2}\/\d{2}$/,
    'DD/MM/YYYY': /^\d{2}\/\d{2}\/\d{4}$/,
    'MM/DD/YYYY': /^\d{2}\/\d{2}\/\d{4}$/,
    'YYYY-MM-DD HH:mm:ss': /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/,
  };
  
  const regex = formatRegexMap[format];
  if (!regex) {
    return false;
  }
  
  if (!regex.test(dateString)) {
    return false;
  }
  
  // 验证日期是否有效
  const date = new Date(dateString);
  return !isNaN(date.getTime());
}

/**
 * 清理和验证输入数据
 */
export function sanitizeInput(input: string): string {
  return input
    .trim()
    .replace(/[<>]/g, '') // 移除可能的HTML标签
    .replace(/['"]/g, '') // 移除引号
    .substring(0, 1000); // 限制长度
}
